/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 * */

// AmzServer - Tototoy's server model.
// Author: tonyjobmails@gmail.com (tonyhack).
//
// Define class TCPCommunicateTask.
//
// TCPCommunicateTask is a version of CommunicateTask under TCP protocol.
//

#ifndef __TCP__COMMUNICATE__TASK__H
#define __TCP__COMMUNICATE__TASK__H

#include "communicate_task.h"
#include "tcp_socket.h"
#include "epoller.h"
#include "tcp_buffer_socket_communicator.h"
#include "tcp_packet_socket_communicator.h"

namespace amz {

TCPCommunicateTask::TCPCommunicateTask(int socket,
       const TCPCommunicateTaskPool *pool,
       const TCPCommunicateConfigure &configure) :
       CommunicateTaskPool(configure.configure), pool_(pool) {
  this->InitializeCommunicator(configure);
  this->temp_buffer_.PreWrite(
         CommunicateConfigure::GetInstance()->GetUnitMessageSize());
}

TCPCommunicateTask::~TCPCommunicateTask() {
  this->FinalizeCommunicator();
}

bool TCPCommunicateTask::Register(Epoller &epoller, int events) {
  return epoller.Register(this->communicator_->GetSocket(), events, this);
}

bool TCPCommunicateTask::Unregister(Epoller &epoller) {
  return epoller.Register(this->communicator_->GetSocket());
}

bool TCPCommunicateTask::SendApplication() {
  int size = this->message_queue_send_.Remove(this->temp_buffer_.HeadPointer(),
       CommunicateConfigure::GetInstance()->GetUnitMessageSize());
  if(size > 0) {
    if(this->communicator_->Send(this->temp_buffer_.HeadPointer(), size) <= 0) {
      LOG(ERROR) << "Send application error.";
      return false;
    }
    return true;
  }
  return false;
}

bool TCPCommunicateTask::ReceiveApplication() {
  
}
bool TCPCommunicateTask::Send() {
}
bool TCPCommunicateTask::Receive() {
}


void TCPCommunicateTask::InitializeCommunicator(
       const TCPCommunicateConfigure &configure) {
  switch(configure.type_) {
    case TCP_COMMUNICATE_TYPE_BUFFER:
      this->communicator_ = new TCPBufferSocketCommunicator(
             socket, configure.compress_, configure.encrypt_)
      break;
    case TCP_COMMUNICATE_TYPE_PACKET:
      this->communicator_ = new TCPBufferPacketCommunicator(
             socket, configure.compress_, configure.encrypt_)
      break;
    default:
      LOG(ERROR) << "Error TCPCommunicateType value.";
      break;
  }
}
void TCPCommunicateTask::FinalizeCommunicator() {
  if(this->communicator_ != NULL) {
    delete this->communicator_;
    this->communicator_ = NULL;
  }
}

}  // namespace amz

#endif  // __TCP__COMMUNICATE__TASK__H

